<template>
  <div class="footer">
    <div class="subject start" v-if="recorderState == RecorderTypeEnum.end" @click="handleStart">
      <img width="40" height="40" src="../assets/microphone.png" />
    </div>
    <div class="subject end" v-else @click="handleStop">
      <span class="icon"></span>
    </div>
    <div class="subsidiary" v-if="recorderState == RecorderTypeEnum.start">
      <CaretRightOutlined class="icon" @click="handlePause" />
      <span style="margin-top: 8px">继续</span>
    </div>
    <div class="subsidiary" v-if="recorderState == RecorderTypeEnum.pause">
      <PauseOutlined class="icon" @click="handleResume" />
      <span style="margin-top: 8px">暂停</span>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, defineExpose } from 'vue'
import { CaretRightOutlined, PauseOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import { debounce } from 'lodash-es'
import { RecorderTypeEnum, AIStatusEnum } from '../types.d'
import { handleSecondsToHms } from '../util'
import { useChatBotStore } from '../chat-bot-store'

const props = defineProps({
  handleScrollBottom: Function
})
const chatBotStore = useChatBotStore()
// 录音状态
const recorderState = ref(RecorderTypeEnum.end)
// 录音文案切割下标，因为录音有总结，文案会造成重复
let recorderEndIndex = 0

const handleStart = debounce(() => {
  window.startRecordMethod((data) => {
    if (!data) {
      message.error('无法获取录音设备或权限')
    } else {
      chatBotStore.dialogList.push({
        user: {
          content: {
            time: '0',
            src: '',
            text: '',
            state: RecorderTypeEnum.start
          }
        }
      })
      recorderState.value = RecorderTypeEnum.start
      // 自动发出一条信息后要回到底部
      props?.handleScrollBottom &&
        setTimeout(() => {
          props?.handleScrollBottom?.()
        }, 300)
    }
  })
}, 200)

const handlePause = () => {
  window.pauseRecordMethod()
  recorderState.value = RecorderTypeEnum.pause

  const latestDialog = chatBotStore.dialogList[chatBotStore.dialogList.length - 1]
  latestDialog.user.content.state = RecorderTypeEnum.pause
}

const handleResume = () => {
  window.resumeRecordMethod()
  recorderState.value = RecorderTypeEnum.start

  const latestDialog = chatBotStore.dialogList[chatBotStore.dialogList.length - 1]
  latestDialog.user.content.state = RecorderTypeEnum.start
}

const handleStop = debounce(() => {
  window.stopRecordMethod((src) => {
    const latestDialog = chatBotStore.dialogList[chatBotStore.dialogList.length - 1]
    latestDialog.user.content.src = src
    latestDialog.user.content.state = RecorderTypeEnum.end
    latestDialog.ai = {
      content: '',
      status: AIStatusEnum.loading
    }
    recorderEndIndex = 0
    recorderState.value = RecorderTypeEnum.end
    chatBotStore.getAIAnswer(latestDialog.user.content.text || '1', props?.handleScrollBottom)
  })
}, 100)

const handleEmpty = () => {
  if (recorderState.value != RecorderTypeEnum.end) {
    window.stopRecordMethod()
    recorderState.value = RecorderTypeEnum.end
  }
}

onMounted(() => {
  // 初始化录音连接实例
  window.initWebSocketConnectMethod({
    stateHandle: (connState) => {
      if (connState == 0) {
        // 连接成功
        console.log('连接成功')
      }
      if (connState == 1) {
        // 关闭连接
        console.log('关闭连接')
      }
      if (connState == 2) {
        // 连接失败
        message.error('连接失败,请稍后再试')
      }
    },
    msgHandle: (data) => {
      const latestDialog = chatBotStore.dialogList[chatBotStore.dialogList.length - 1]
      const oldText = latestDialog.user.content.text
      if(data?.mode=="2pass-offline" || data?.mode=="offline") {
        const newText = oldText.substring(0, recorderEndIndex) + data.text;
        latestDialog.user.content.text = newText
        recorderEndIndex = newText.length
      } else {
        latestDialog.user.content.text = oldText + data.text
      }
      props?.handleScrollBottom?.()
    },
    recorder: {
      onProcess: (buffer, powerLevel, bufferDuration) => {
        const latestDialog = chatBotStore.dialogList[chatBotStore.dialogList.length - 1]
        latestDialog.user.content.time = handleSecondsToHms(Math.ceil(bufferDuration / 1000))
      }
    }
  })
})

onUnmounted(() => {
  handleEmpty()
})

defineExpose({ handleEmpty })
</script>

<style lang="less" scoped>
.footer {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  box-sizing: border-box;

  .subject {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
  }

  .start {
    background: linear-gradient(180deg, #4f54ff 1%, #3499ff 100%);
  }

  .start:hover {
    box-shadow: 0px 8px 20px 0px rgba(88, 99, 255, 0.5);
  }

  .end {
    background: #ffffff;

    .icon {
      width: 26px;
      height: 26px;
      border-radius: 4px;
      background-color: rgb(245, 63, 63);
    }
  }

  .end:hover {
    box-shadow: 0px 8px 20px 0px rgba(203, 38, 52, 0.2);
  }

  .subsidiary {
    position: absolute;
    left: 70%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    font-size: 12px;

    .icon {
      cursor: pointer;
      font-size: 24px;
    }

    .icon:hover {
      color: #1677ff;
    }
  }
}
</style>
